package com.ls.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLConnection;

import javax.servlet.http.HttpServletResponse;

import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.ls.config.PicturesUploadProperties;

@Controller
@SessionAttributes("picturePath")
public class ProfileController {
	
	private final Resource pictureDir;
	
	private final Resource anonymousPicture;
	
	@ModelAttribute("picturePath")
	public Resource picturePath() {
		return anonymousPicture;
	}
	
	@Autowired
	public ProfileController(PicturesUploadProperties picturesUploadProperties) {
		pictureDir = picturesUploadProperties.getUploadPath();
		anonymousPicture = picturesUploadProperties.getAnonymousPicture();
	}

	public static final Resource PICTURES_DIR = new FileSystemResource(
			"./pictures");
	
	@RequestMapping("/uploadedPicture")
	public void getUploadedPicture(HttpServletResponse response, @ModelAttribute("picturePath") Resource picturePath) throws IOException {
		// 将图片写入到响应中，页面显示图片
		/*ClassPathResource classPathResource = new ClassPathResource("/images/anonymous.png");
		response.setHeader("Content-Type", URLConnection.guessContentTypeFromName(classPathResource.getFilename()));
		IOUtils.copy(classPathResource.getInputStream(), response.getOutputStream());*/
		
		// 配置文件设置文件路径
		response.setHeader("Content-Type", URLConnection.guessContentTypeFromName(anonymousPicture.getFilename()));
		IOUtils.copy(picturePath.getInputStream(), response.getOutputStream());
		/*
		 * 动态显示上传图片
		 * 书中使用：Files.copy(picturePath, response.getOutputStream());
		 * picturePath 是Path，
		 * 报错:Resolved [org.springframework.beans.TypeMismatchException: Failed to convert value of type 'org.springframework.core.io.ClassPathResource' to required type 'java.nio.file.Path'
		 * Cannot convert value of type 'org.springframework.core.io.ClassPathResource' to required type 'java.nio.file.Path': PropertyEditor [org.springframework.beans.propertyeditors.PathEditor] returned inappropriate value of type 'org.springframework.core.io.ClassPathResource']
		 * 
		 * 使用 Resource 替代解决
		 */
		/*IOUtils.copy(picturePath.getInputStream(), response.getOutputStream());*/
	    // 添加 Path 参数，显示上传图片,  path: java.nio.file.Path
		/*System.out.println("path method" + picturePath.toString());*/
		/*response.setHeader("Content-Type", URLConnection.guessContentTypeFromName(picturePath.toString()));
		Files.copy(picturePath, response.getOutputStream());*/
	}

	@RequestMapping("/upload")
	public String upload() {
		return "profile/uploadPage";
	}

	@RequestMapping(value = "/upload", method = RequestMethod.POST)
	public String onUpload(MultipartFile file, RedirectAttributes redirectAttributes, Model model) throws IOException {
		/*
		 * 放入方法中  copyFileToPictures 
		 * 
		String filename = file.getOriginalFilename();
		File tempFile = File.createTempFile("pic", getFileExtension(filename),
				PICTURES_DIR.getFile());
		try (InputStream in = file.getInputStream();
				OutputStream out = new FileOutputStream(tempFile)) {
			IOUtils.copy(in, out);

		}*/
		// 添加测试异常处理
		/*throw new IOException("Some message");*/
		// 添加文件类型校验
		if (file.isEmpty() || !isImage(file)) {
			redirectAttributes.addFlashAttribute("error", "Incorrect file. Please upload a picture.");
			
			return "redirect:/upload";
		}
		Resource picturePath = copyFileToPictures(file);
		model.addAttribute("picturePath", picturePath);
		return "profile/uploadPage";
	}

	private static String getFileExtension(String name) {
		return name.substring(name.lastIndexOf("."));
	}
	
	/**
	 * 是否是图片
	 * @param file
	 * @return
	 */
	private Boolean isImage(MultipartFile file) {
		return file.getContentType().startsWith("image");
	}
	
	/**
	 * 文件复制
	 * @param file
	 * @return
	 * @throws IOException
	 */
	private Resource copyFileToPictures(MultipartFile file) throws IOException {
		// 指定上传目录
		/*String fileExtension = getFileExtension(file.getOriginalFilename());
		File tempFile = File.createTempFile("pic", fileExtension, PICTURES_DIR.getFile());
		try(InputStream in = file.getInputStream();
				OutputStream out = new FileOutputStream(tempFile)) {
			IOUtils.copy(in, out);
		}
		return new FileSystemResource(tempFile);*/
		
		String fileExtension = getFileExtension(file.getOriginalFilename());
		File tempFile = File.createTempFile("pic", fileExtension, pictureDir.getFile());
		try(InputStream in = file.getInputStream();
				OutputStream out = new FileOutputStream(tempFile);){
			IOUtils.copy(in, out);
		}
		return new FileSystemResource(tempFile);
	}
	
	// 添加IOException 处理
	@ExceptionHandler(IOException.class)
	public ModelAndView handleIOException(IOException exception) {
		ModelAndView modelAndView = new ModelAndView("/profile/uploadPage");
		modelAndView.addObject("error", exception.getMessage());
		return modelAndView;
	}
}
